package com.laike.pay.qrdecode;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.Toast;

import com.laike.pay.R;
import com.laike.pay.activity.DealDetailsActivity;
import com.laike.pay.base.BaseActivity;
import com.laike.pay.bean.PayOrder;
import com.laike.pay.greendao.PayOrderDao;
import com.laike.pay.http.BaseCallback;
import com.laike.pay.http.HttpRetrofit;
import com.laike.pay.http.ParamsUtils;
import com.laike.pay.http.Result;
import com.laike.pay.http.api.ApiName;
import com.laike.pay.http.api.SerivceApi;
import com.laike.pay.utils.GreenDaoManager;
import com.laike.pay.utils.ProgressDialogUtils;
import com.laike.pay.utils.SharedPreferencesUtils;
import com.laike.pay.utils.ToastUtils;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.util.List;

import retrofit2.Call;
import retrofit2.Response;

public class MipcaActivityCapture extends BaseActivity implements Callback, BaseCallback<Result<PayOrder>> {

    private static int RESULT_LOAD_IMAGE = 1000;
    private CaptureActivityHandler handler;
    private ViewfinderView viewfinderView;
    private boolean hasSurface;
    private InactivityTimer inactivityTimer;
    private MediaPlayer mediaPlayer;
    private boolean playBeep;
    private static final float BEEP_VOLUME = 0.10f;
    private boolean vibrate;
    private Dialog dialog;
    private SurfaceHolder surfaceHolder;
    private BarcodeFormat barcodeFormat;
    private SurfaceView surfaceView;
    private int type = 0;

    @Override
    public int getContentViewResId() {
        return R.layout.activity_capture;
    }

    @Override
    public void intiViews() {
        CameraManager.init(this.getApplicationContext());
        viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view1);
        surfaceView = (SurfaceView) findViewById(R.id.preview_view1);
        hasSurface = false;
        surfaceHolder = surfaceView.getHolder();
        inactivityTimer = new InactivityTimer(this);
        barcodeFormat = new BarcodeFormat();
        barcodeFormat.add(BarcodeFormat.BARCODE);
        barcodeFormat.add(BarcodeFormat.QRCODE);
    }

    @Override
    public String setTitle() {
        Intent intent = getIntent();
        String title = "";
        if (null != intent) {
            title = intent.getStringExtra("title");
            type = intent.getIntExtra("type", 0);
        }
        return title;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        CameraManager.get().closeDriver();
    }

    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        super.onDestroy();
    }

    @SuppressLint("StaticFieldLeak")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};

            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            new AsyncTask<String, Void, String>() {

                @Override
                protected String doInBackground(String... arg0) {
                    // TODO Auto-generated method stub
                    return DecodeEntry.decodeFromFile(arg0[0], barcodeFormat);
                }

                @Override
                protected void onPreExecute() {
                    dialog = ProgressDialog.show(MipcaActivityCapture.this, null, "Decoding...");
                    CameraManager.get().closeDriver();
                }

                @Override
                protected void onPostExecute(String result) {
                    initCamera(surfaceHolder);
                    if (dialog != null) {
                        dialog.dismiss();
                    }
                    if (type == 400) {
                        Intent resultIntent = new Intent();
                        Bundle bundle = new Bundle();
                        bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
                        bundle.putString(CodeUtils.RESULT_STRING, result);
                        resultIntent.putExtras(bundle);
                        MipcaActivityCapture.this.setResult(RESULT_OK, resultIntent);
                        MipcaActivityCapture.this.finish();
                    } else
                        success(result);
                }

            }.execute(picturePath);
            cursor.close();
        }
    }

    /**
     * 收款失败
     */
    private void fail() {
        Intent resultIntent = new Intent();
        Bundle bundle = new Bundle();
        bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
        bundle.putString(CodeUtils.RESULT_STRING, "");
        resultIntent.putExtras(bundle);

    }

    /*
    收款成功
     */
    private void success(String result) {
        String str = result.trim();
        if (type == 100) {//查单
            ProgressDialogUtils.showProgress(this, getString(R.string.select_deal_now));
            ProgressDialogUtils.getmDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);
            if (str.length() == 17) {
                //内部订单号
                HttpRetrofit.getInstance().getInterfaceApi(SerivceApi.class).request(SharedPreferencesUtils.getAppid()
                        , ApiName.SELECT_DEAL, "", str, ParamsUtils.getOrderParams(str)).enqueue(this);
            } else if (str.length() > 17) {
                //第三方订单号
                HttpRetrofit.getInstance().getInterfaceApi(SerivceApi.class).request(SharedPreferencesUtils.getAppid()
                        , ApiName.SELECT_DEAL, str, "", ParamsUtils.getOrderParams(str)).enqueue(this);
            }
        } else if (type == 200) {//收款
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
            bundle.putString(CodeUtils.RESULT_STRING, result);
            resultIntent.putExtras(bundle);
            this.setResult(RESULT_OK, resultIntent);
            this.finish();
        } else if (type == 300) {//退款
            ProgressDialogUtils.showProgress(this, getString(R.string.refund_now));
            if (str.length() == 17) {
                HttpRetrofit.getInstance().getInterfaceApi(SerivceApi.class).refund(SharedPreferencesUtils.getAppid(), ApiName.RE_FUND, ParamsUtils.refund(str),
                        "", str, SharedPreferencesUtils.getWorkMenId()).enqueue(callback);
            } else if (str.length() > 17) {
                HttpRetrofit.getInstance().getInterfaceApi(SerivceApi.class).refund(SharedPreferencesUtils.getAppid(), ApiName.RE_FUND, ParamsUtils.refund(str), str
                        , "", SharedPreferencesUtils.getWorkMenId()).enqueue(callback);
            }
        }
    }

    /**
     * 退款回调
     */
    BaseCallback<Result<PayOrder>> callback = new BaseCallback<Result<PayOrder>>() {
        @Override
        public void onResponse(Call<Result<PayOrder>> call, Response<Result<PayOrder>> response) {
            ProgressDialogUtils.dismissProgress();
            if (response.code() == 200) {
                if (response.body().getStatus().equals("1")) {
                    PayOrder order = response.body().getData();
                    ToastUtils.showToast(MipcaActivityCapture.this, R.string.refund_succ);
                    PayOrderDao payOrderDao = GreenDaoManager.getInstance().getNewSession().getPayOrderDao();
                    List<PayOrder> list = payOrderDao.queryBuilder().where(PayOrderDao.Properties.Out_trade_no.eq(order.getOut_trade_no())).build().list();
                    if (list != null && list.size() != 0) {
                        order.setId(list.get(0).getId());
                    }
                    payOrderDao.update(order);
                    Intent intent = new Intent(MipcaActivityCapture.this, DealDetailsActivity.class);
                    intent.putExtra("type", 300);
                    intent.putExtra("order", order);
                    String pay_type = order.getPay_type();
                    intent.putExtra("index", "22".endsWith(pay_type) ? 1 : 0);
                    startActivity(intent);
                    finish();
                } else {
                    ToastUtils.showToast(MipcaActivityCapture.this, response.body().getInfo());
                    finish();
                }
            }
        }

        @Override
        public void onFailure(Call<Result<PayOrder>> call, Throwable t) {
            ProgressDialogUtils.dismissProgress();
            Log.v("onFailure", "error message:" + t.getMessage());
        }
    };

    /**
     * @param result
     */
    public void handleDecode(String result) {
        // inactivityTimer.onActivity();
//		playBeepSoundAndVibrate();
        Logger.d("------" + result);
        if (result.equals("")) {
            Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show();
            if (type == 400) {
                Intent resultIntent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
                bundle.putString(CodeUtils.RESULT_STRING, "");
                resultIntent.putExtras(bundle);
                this.setResult(RESULT_OK, resultIntent);
                this.finish();
            } else
                fail();
        } else {
            if (type == 400) {
                Intent resultIntent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
                bundle.putString(CodeUtils.RESULT_STRING, result);
                resultIntent.putExtras(bundle);
                this.setResult(RESULT_OK, resultIntent);
                this.finish();
            } else
                success(result);
        }
    }

    private void initCamera(SurfaceHolder surfaceHolder) {
        try {
            CameraManager.get().openDriver(surfaceHolder);
        } catch (IOException ioe) {
            return;
        } catch (RuntimeException e) {
            return;
        }
        if (handler == null) {
            handler = new CaptureActivityHandler(this, barcodeFormat);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!hasSurface) {
            hasSurface = true;
            initCamera(holder);
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;

    }

    public ViewfinderView getViewfinderView() {
        return viewfinderView;
    }

    public Handler getHandler() {
        return handler;
    }

    public void drawViewfinder() {
        viewfinderView.drawViewfinder();

    }

    private void initBeepSound() {
        if (playBeep && mediaPlayer == null) {
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);

            AssetFileDescriptor file = getResources().openRawResourceFd(
                    R.raw.beep);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }

    private static final long VIBRATE_DURATION = 200L;

    private void playBeepSoundAndVibrate() {
        if (playBeep && mediaPlayer != null) {
            mediaPlayer.start();
        }
        if (vibrate) {
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(VIBRATE_DURATION);
        }
    }

    /**
     * When the beep has finished playing, rewind to queue up another one.
     */
    private final OnCompletionListener beepListener = new OnCompletionListener() {
        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.seekTo(0);
        }
    };

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.KEYCODE_FOCUS:
            case KeyEvent.KEYCODE_CAMERA:
                return true;
            case KeyEvent.KEYCODE_VOLUME_UP:
                CameraManager.get().zoomIn();
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                CameraManager.get().zoomOut();
                return true;
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    public void onResponse(Call<Result<PayOrder>> call, Response<Result<PayOrder>> response) {
        ProgressDialogUtils.dismissProgress();
        if (response.code() == 200) {
            if (response.body().getStatus().equals("1")) {
                PayOrder order = response.body().getResult();
                Intent intent = new Intent(this, DealDetailsActivity.class);
                String pay_type = order.getPay_type();
                intent.putExtra("index", "22".endsWith(pay_type) ? 1 : 0);
                intent.putExtra("order", order);
                startActivity(intent);
            } else {
                ToastUtils.showToast(this, response.body().getInfo(), 3000);
            }
        }
        finish();
    }

    @Override
    public void onFailure(Call<Result<PayOrder>> call, Throwable t) {
        ProgressDialogUtils.dismissProgress();
        Log.v("onFailure", "onFailure ! message:" + t.getMessage());
    }
}